package com.bluedot.controller;

import com.bluedot.pojo.pack.PreMappedStatement;
import com.bluedot.pojo.pack.ResultEntity;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 消息队列
 *
 * @author chenzou'quan
 */
public class MessageQueue {

    /** 同步请求队列 */
    private static  Queue<PreMappedStatement> requestQueue = new ConcurrentLinkedQueue<>();

    /** 同步响应队列 */
    private static Queue<ResultEntity> responseQueue = new ConcurrentLinkedQueue<>();

    /** 同步请求缓冲容器 */
    protected volatile PreMappedStatement request = null;
    /** 同步响应缓冲容器 */
    protected volatile ResultEntity response = null;

    /** 异步请求队列 */
    private static volatile Queue<PreMappedStatement> preMappedStatements = new LinkedList<>();

    /**
     * 队列管道运行方法
     * @param param
     * @return
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    protected static ResultEntity addQueue(PreMappedStatement param) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        String[] split = param.getMethodType().split("/");
        // 1. 区分同步方法和异步方法
        if ("query".equals(split[split.length - 1]) || split[split.length - 1].contains("query")
                || split[split.length - 1].contains("export") || "login".equals(split[split.length - 1])
                || split[split.length - 1].contains("do") || "forgetPassword".equals(split[split.length - 1])
                || "queryMessage".equals(split[split.length - 1])
                || split[split.length - 1].contains("getInfo")
                ||"queryAllAlgorithm".equals(split[split.length - 1])||"queryByUserId".equals(split[split.length - 1])
                ||"queryDeleteAlgorithm".equals(split[split.length - 1]) ||"queryHotNumber".equals(split[split.length - 1])
                ||"insertLogin".equals(split[split.length - 1]) || "avatarwaveanalyze".equals(split[split.length - 1])
        ) {
            // 同步方法
            requestQueue.add(param);
            DistributeClass.update(true);
            return responseQueue.remove();
        }else {
            // 异步方法
            preMappedStatements.add(param);
            new Thread(() -> {
                try {
                    DistributeClass.update(false);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }).start();
            return ResultEntity.successWithoutData();
        }

    }

    /**
     * 普通管道执行方法
     * @param param
     * @return
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    protected static ResultEntity addRequest(PreMappedStatement param) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        String[] split = param.getMethodType().split("/");
        // 1. 区分同步方法和异步方法
        if ("query".equals(split[split.length - 1]) || split[split.length - 1].contains("query")
                || split[split.length - 1].contains("export") || "login".equals(split[split.length - 1])
                || split[split.length - 1].contains("do") || "forgetPassword".equals(split[split.length - 1])
                || "queryMessage".equals(split[split.length - 1])
                || split[split.length - 1].contains("getInfo")
                ||"queryAllAlgorithm".equals(split[split.length - 1])||"queryByUserId".equals(split[split.length - 1])
                ||"queryDeleteAlgorithm".equals(split[split.length - 1]) ||"queryHotNumber".equals(split[split.length - 1])
                ||"insertLogin".equals(split[split.length - 1])
        ) {
            // 同步方法
            DistributeClass messageQueue = new DistributeClass();
            messageQueue.request = param;
            messageQueue.updateRequest(true);
            return messageQueue.response;
        }else {
            // 异步方法
            preMappedStatements.add(param);
            new Thread(() -> {
                try {
                    DistributeClass.update(false);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }).start();
            return ResultEntity.successWithoutData();
        }

    }





    protected static Queue<ResultEntity> getResponseQueue() {
        return responseQueue;
    }

    protected static Queue<PreMappedStatement> getRequestQueue() {
        return requestQueue;
    }

    protected static Queue<PreMappedStatement> getPreMappedStatements() {
        return preMappedStatements;
    }
}
